
/*
 * Hlpay-Plus aggregate payment system. Copyright
 * (c) 2022-2023 Hlpay Team Copyright has the right of final interpretation.
 */

package com.hlkj.pay.app.adminuser.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;
import org.springframework.util.StringUtils;

import com.hlkj.framework.caches.service.RedisTemplateService;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.pojo.LocalContext;
import com.hlkj.framework.common.pojo.LocalRequest;
import com.hlkj.framework.common.pojo.PageResult;
import com.hlkj.framework.common.provider.Aes256EncryptionProvider;
import com.hlkj.framework.common.util.collection.CollectionUtils;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.app.adminuser.IUserPermissionAppService;
import com.hlkj.pay.app.merchant.IMerchantInfoAppService;
import com.hlkj.pay.app.transfer.RoleDoToResp;
import com.hlkj.pay.app.transfer.UserDoToResp;
import com.hlkj.pay.common.AdminUserResultCode;
import com.hlkj.pay.common.CommonResultCode;
import com.hlkj.pay.common.MerchantResultCode;
import com.hlkj.pay.common.constants.AdminRedisConstant;
import com.hlkj.pay.dto.LocalAdminUserRequest;
import com.hlkj.pay.dto.admin.AdminUserDto;
import com.hlkj.pay.dto.admin.RoleQueryDto;
import com.hlkj.pay.dto.admin.UserPermissionDto;
import com.hlkj.pay.dto.common.DataFilterConfig;
import com.hlkj.pay.dto.merchant.MerchantAccessInfoPageDto;
import com.hlkj.pay.dto.merchant.MerchantAccessInfoPageQueryDto;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.infrastructure.model.admin.PermissionDO;
import com.hlkj.pay.infrastructure.model.admin.RoleDO;
import com.hlkj.pay.infrastructure.model.admin.RolePermissionMappingDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantConfigDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantInfoDO;
import com.hlkj.pay.service.admin.IAdminUserService;
import com.hlkj.pay.service.admin.IPermissionService;
import com.hlkj.pay.service.admin.IRoleService;
import com.hlkj.pay.service.common.IBusinessLogService;
import com.hlkj.pay.service.common.IPlatFormConfigService;
import com.hlkj.pay.service.merchant.IMerchantAccessService;
import com.hlkj.pay.service.merchant.IMerchantService;
import com.hlkj.pay.util.PermissionCoverUtils;
import com.hlkj.pay.vo.admin.req.user.AdminCommonUserLoginReq;
import com.hlkj.pay.vo.admin.req.user.AdminUserCheckPermissionReq;
import com.hlkj.pay.vo.admin.resp.user.AdminUserAccountResp;
import com.hlkj.pay.vo.admin.resp.user.AdminUserAuthorityResp;
import com.hlkj.pay.vo.admin.resp.user.AdminUserPermissionResp;
import com.hlkj.pay.vo.admin.resp.user.CheckPermissionResp;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.StringPool;

/**
 * @author HlpayTeam
 * @date 2024/09/10 14:50
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserPermissionAppServiceImpl implements IUserPermissionAppService {

    private final IAdminUserService userService;

    private final IRoleService roleService;

    private final IPermissionService permissionService;

    private final IBusinessLogService businessLogService;

    private final RedisTemplateService redisTemplateService;

    private final IMerchantAccessService merchantAccessService;

    private final IMerchantInfoAppService merchantInfoAppService;

    private final IMerchantService merchantService;

    private final Aes256EncryptionProvider aes256EncryptionProvider;

    private final IPlatFormConfigService platFormConfigService;

    @Override
    public CommonResult<AdminUserAccountResp> login(AdminCommonUserLoginReq adminCommonUserLoginReq) {
        log.info("login adminCommonUserLoginReq:{}", JsonUtils.toJsonString(adminCommonUserLoginReq));
        try {
            LocalRequest localUserRequest = LocalContext.get();
            AdminUserDto adminUserDto = userService.queryUserDto(localUserRequest.getUserId());
            adminUserDto.setPhone(adminUserDto.getPhoneEncrypt());
            adminUserDto.setEmail(adminUserDto.getEmailEncrypt());
            // loginTime
            userService.updateUserLoginTime(localUserRequest.getUserId(), adminCommonUserLoginReq.getCheckAgreement());
            // 失效权限变更标记
            userService.expirePermissionChangeStatus();
            // add log
            businessLogService.addLoginInLog();
            AdminUserAccountResp adminUserAccountResp = UserDoToResp.INSTANCE.domainToAccountResp(adminUserDto);
            if (!CommonEnum.YES_NO_TYPE.YES.getCode().equals(adminUserDto.getUpdatePwdFlag())) {
                adminUserAccountResp.setFristLogin(Boolean.TRUE);
            }
            return CommonResult.success(adminUserAccountResp);
        }
        catch (Exception e) {
            log.error("login error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<AdminUserPermissionResp> userPermission(Long userId) {
        try {
            if (userId == null) {
                userId = LocalContext.get().getUserId();
            }
            AdminUserDto adminUserDto = userService.queryUserDto(userId);
            if (adminUserDto == null) {
                return CommonResult.error(AdminUserResultCode.USER_DOES_NOT_EXIST);
            }
            if (CollectionUtils.isEmpty(adminUserDto.getRoleCodes())) {
                return CommonResult.error(AdminUserResultCode.USER_ROLE_NOT_EXIST);
            }

            CommonResult<UserPermissionDto> userPermissionCommonResult = userPermission(adminUserDto);
            if (!userPermissionCommonResult.isSuccess()) {
                return CommonResult.error(userPermissionCommonResult.getCode(), userPermissionCommonResult.getMsg());
            }
            // 失效权限变更标记
            userService.expirePermissionChangeStatus();
            // String language =
            // WebFrameworkUtils.getRequest().getHeader(LanguageEnum.LANGUAGE.getCode());
            // if (org.springframework.util.StringUtils.hasText(language) &&
            // !language.equals(adminUserDto.getLanguage())) {
            // userService.updateLanguage(adminUserDto.getId(),language);
            // adminUserDto.setLanguage(language);
            // }
            AdminUserPermissionResp adminUserPermissionResp = new AdminUserPermissionResp();
            BeanUtils.copyProperties(adminUserDto, adminUserPermissionResp);
            try {
                adminUserPermissionResp.setPhone(aes256EncryptionProvider.decrypt(adminUserDto.getPhoneEncrypt()));
            }
            catch (Exception e) {
                adminUserPermissionResp.setPhone(adminUserDto.getPhoneEncrypt());
            }
            if (StringUtils.hasText(adminUserDto.getPartCode())) {
                // OrganizationDO organizationDO =
                // storeService.queryStoreDetail(adminUserDto.getPartCode());
                // adminUserPermissionResp.setPartName(organizationDO == null ? "" :
                // organizationDO.getOrganizationName());
            }
            UserPermissionDto permissionDto = userPermissionCommonResult.getData();
            List<String> permissionCodes = null;
            if (CollectionUtils.isNotEmpty(permissionDto.getRolePermissionList())) {
                permissionCodes = permissionDto.getRolePermissionList().stream().map(RolePermissionMappingDO::getPermissionCode).collect(Collectors.toList());
            }
            adminUserPermissionResp.setSuperAdminFlag(permissionDto.isAdminRoleFlag());
            adminUserPermissionResp.setMenuList(
                    PermissionCoverUtils.permissionMenuList(permissionDto.getPermissionList(), permissionDto.isAdminRoleFlag(), permissionDto.getRolePermissionList()));
            adminUserPermissionResp.setPermissions(PermissionCoverUtils.userPermissionList(permissionDto.getPermissionList(), permissionDto.isAdminRoleFlag(), permissionCodes));
            adminUserPermissionResp.setRoles(RoleDoToResp.INSTANCE.roleRespList(permissionDto.getRoleList()));

            if (StringUtils.hasText(adminUserDto.getSn())) {
                MerchantConfigDO merchantConfigDO = merchantInfoAppService.queryConfig(adminUserDto.getSn());
                if (CollectionUtils.isNotEmpty(merchantConfigDO.getChannelCodeList()) && CollectionUtils.isNotEmpty(merchantConfigDO.getProviderCodeList())) {
                    adminUserPermissionResp.setProviderCode(merchantConfigDO.getProviderCodeList().get(0));
                    adminUserPermissionResp.setChannelCode(merchantConfigDO.getChannelCodeList().get(0));
                }
                MerchantAccessInfoPageQueryDto merchantAccessInfoPageQueryDto = new MerchantAccessInfoPageQueryDto();
                // merchantAccessInfoPageQueryDto.setSortingFields("a.id-asc");
                merchantAccessInfoPageQueryDto.setSn(adminUserDto.getSn());
                merchantAccessInfoPageQueryDto.setPageSize(1);
                merchantAccessInfoPageQueryDto.setPageNo(1);
                PageResult<MerchantAccessInfoPageDto> merchantAccessInfoPageDtoPageResult = merchantAccessService.queryPage(merchantAccessInfoPageQueryDto);
                List<MerchantAccessInfoPageDto> list = merchantAccessInfoPageDtoPageResult.getList();
                if (CollectionUtils.isNotEmpty(list)) {
                    adminUserPermissionResp.setMerchantAccessStatus(list.get(0).getStatus());
                }
                // 返回增加商户类型，0=普通商户，1=平台商户
                MerchantInfoDO merchantInfoDO = merchantService.queryMerchant(adminUserDto.getSn());
                if(ObjectUtil.isNotEmpty(merchantInfoDO)){
                    adminUserPermissionResp.setMerType(merchantInfoDO.getMerType());
                }

            }
            return CommonResult.success(adminUserPermissionResp);
        }
        catch (Exception e) {
            log.error("userPermission error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> logout() {
        try {
            // loginTime
            businessLogService.addLogOutLog();
            // 删除用户缓存
            userService.delLogInUserCache();
            return CommonResult.success(null);
        }
        catch (Exception e) {
            log.error("logout error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<CheckPermissionResp> checkPermission(AdminUserCheckPermissionReq adminUserCheckPermissionReq) {
        log.info("checkPermission:{}", JsonUtils.toJsonString(adminUserCheckPermissionReq));
        // 微信小程序放行
        if(StrUtil.isNotEmpty(adminUserCheckPermissionReq.getClientType())){
            // 判断是否微信小程序
            if(adminUserCheckPermissionReq.getClientType().equalsIgnoreCase(CommonEnum.CLIENT_TYPE.WX_MINI.getDesc())){
                log.info("checkPermission WX_MINI 微信小程序放行");
                return CommonResult.success();
            }
        }

        StopWatch stopWatch = new StopWatch("checkPermission");
        stopWatch.start("queryAuthority");
        CommonResult<AdminUserAuthorityResp> userAuthorityRespCommonResult = queryAuthority(adminUserCheckPermissionReq);
        // CommonResult<AdminUserAuthorityResp> userAuthorityRespCommonResult =
        // CommonResult.success();
        stopWatch.stop();
        if (!userAuthorityRespCommonResult.isSuccess()) {
            return CommonResult.error(userAuthorityRespCommonResult.getCode(), userAuthorityRespCommonResult.getMsg());
        }
        stopWatch.start("addBehaviorLog");
        AdminUserAuthorityResp authorityRespCommonResultData = userAuthorityRespCommonResult.getData();
        if (authorityRespCommonResultData != null) {
            businessLogService.addBehaviorLog(authorityRespCommonResultData.getPermissionCode());
        }
        stopWatch.stop();
        if (log.isDebugEnabled()) {
            log.debug("checkPermission total:{},msg:{}", stopWatch.getTotalTimeMillis(), stopWatch.prettyPrint());
        }
        return CommonResult.success();
    }

    @Override
    public CommonResult<AdminUserAuthorityResp> queryAuthority(AdminUserCheckPermissionReq adminUserCheckPermissionReq) {
        StopWatch stopWatch = new StopWatch("queryAuthority");
        stopWatch.start("queryAuthority-get-cache");
        Long userId = LocalContext.get().getUserId();
        // String authorityKey = authorityKey(userId,
        // adminUserCheckPermissionReq.getPermissionName());
        // String object = (String) redisTemplateService.get(authorityKey);
        // if (StringUtils.hasText(object)) {
        // return JsonUtils.parseObject(object, new
        // TypeReference<CommonResult<AdminUserAuthorityResp>>() {
        // });
        // }
        stopWatch.stop();
        // user info and organizationDO info
        stopWatch.start("adminUserDto");
        AdminUserDto adminUserDto = userService.queryUserDto(userId);
        if (adminUserDto == null) {
            return CommonResult.error(AdminUserResultCode.USER_DOES_NOT_EXIST);
        }
        if (!StringUtils.hasText(adminUserDto.getPartCode())) {
            // return CommonResult.error(AdminUserResultCode.USER_PART_NOT_EXIST);
        }
        if (CollectionUtils.isEmpty(adminUserDto.getRoleCodes())) {
            return CommonResult.error(AdminUserResultCode.USER_ROLE_NOT_EXIST);
        }
        // 非admin 服务接口需要判断是否修改过密码
        // if
        // (!adminUserCheckPermissionReq.getUrl().startsWith(AdminUserConstant.PASS_CHECK_UPDATE_URL_PREFIX)
        // &&
        // !AdminUserEnum.YES_NO_TYPE.YES.getCode().equals(adminUserDto.getUpdatePwdFlag()))
        // {
        // return CommonResult.error(AdminUserResultCode.USER_PWD_MUST_UPDATE);
        // }
        stopWatch.stop();
        stopWatch.start("user-merchant");
        if (StringUtils.hasText(adminUserDto.getSn())) {
            MerchantInfoDO merchantInfoDO = merchantService.queryMerchant(adminUserDto.getSn());
            if (merchantInfoDO == null) {
                return CommonResult.error(MerchantResultCode.MERCHANT_NOT_EXIST);
            }
            if (CommonEnum.YES_NO_TYPE.NO.getCode().equals(merchantInfoDO.getStatus())) {
                return CommonResult.error(MerchantResultCode.MERCHANT_NOT_EFFECT);
            }
        }
        stopWatch.stop();
        // user permission info
        stopWatch.start("userPermissionCommonResult");
        CommonResult<UserPermissionDto> userPermissionCommonResult = userPermission(adminUserDto);
        if (!userPermissionCommonResult.isSuccess()) {
            return CommonResult.error(userPermissionCommonResult.getCode(), userPermissionCommonResult.getMsg());
        }
        UserPermissionDto userPermissionDto = userPermissionCommonResult.getData();
        stopWatch.stop();
        stopWatch.start("permissionDO");

        // interface permission check
        // 返回参数
        AdminUserAuthorityResp adminUserAuthorityResp = new AdminUserAuthorityResp();
        PermissionDO permissionDO = permissionDO(userPermissionDto.getPermissionList(), adminUserCheckPermissionReq);
        if (permissionDO == null) {
            // 解决 admin 没有配置菜单的问题
            if (!userPermissionDto.isAdminRoleFlag()) {
                return CommonResult.error(AdminUserResultCode.USER_PERMISSION_NOT_ACCESS);
            }
        }
        else {
            adminUserAuthorityResp.setPermissionCode(permissionDO.getCode());
        }
        stopWatch.stop();
        adminUserAuthorityResp.setSuperAdminFlag(userPermissionDto.isAdminRoleFlag());
        CommonResult<AdminUserAuthorityResp> commonResult = CommonResult.success(adminUserAuthorityResp);
        stopWatch.start("queryAuthority-set-cache");
        // redisTemplateService.set(authorityKey, JsonUtils.toJsonString(commonResult),
        // AdminRedisConstant.USER_DATA_AUTHORITY_EXPIRE_TIME);
        stopWatch.stop();
        if (log.isDebugEnabled()) {
            log.debug("checkPermission total:{},msg:{}", stopWatch.getTotalTimeMillis(), stopWatch.prettyPrint());
        }
        return commonResult;
    }

    @Override
    public void authorityChange(Long userId) {
        String authorityKey = authorityKey(userId);
        List<String> keys = redisTemplateService.keys(authorityKey);
        if (!CollectionUtils.isEmpty(keys)) {
            redisTemplateService.del(keys);
        }
    }

    /**
     * 通用权限获取
     * 
     * @param adminUserDto
     * @return
     */
    CommonResult<UserPermissionDto> userPermission(AdminUserDto adminUserDto) {
        StopWatch stopWatch = new StopWatch("userPermissionDto");
        stopWatch.start("roleList");
        RoleQueryDto roleQueryDto = new RoleQueryDto();
        roleQueryDto.setCodeList(adminUserDto.getRoleCodes());
        List<RoleDO> roleList = roleService.queryRoleList(roleQueryDto);
        if (CollectionUtils.isEmpty(roleList)) {
            return CommonResult.error(AdminUserResultCode.USER_PERMISSION_NOT_EXIST);
        }
        stopWatch.stop();
        stopWatch.start("queryAllPermission");
        UserPermissionDto userPermissionDto = new UserPermissionDto();
        userPermissionDto.setRoleList(roleList);
        LocalAdminUserRequest localAdminUserRequest = (LocalAdminUserRequest) LocalContext.get();
        List<PermissionDO> permissionList = permissionService.queryAllPermission(localAdminUserRequest.getSysType());
        AtomicReference<Boolean> adminRoleFlagReference = new AtomicReference<>(false);
        roleList.stream().forEach(roleResp -> {
            Boolean superAdminFlag = roleResp.getSuperAdminFlag();
            if (superAdminFlag != null && superAdminFlag) {
                adminRoleFlagReference.set(superAdminFlag);
                return;
            }
        });
        Boolean adminRoleFlag = adminRoleFlagReference.get();
        List<PermissionDO> finalPermissionList;
        List<RolePermissionMappingDO> permissionMappingList = null;
        stopWatch.stop();
        DataFilterConfig dataFilterConfig = platFormConfigService.getDataFilterConfig();
        List<DataFilterConfig.PermissionFilter> permissionFilters = dataFilterConfig.getPermissionFilters();
        Map<Integer, List<DataFilterConfig.PermissionFilter>> collected = permissionFilters.stream()
                .collect(Collectors.groupingBy(DataFilterConfig.PermissionFilter::getSysType));
        List<DataFilterConfig.PermissionFilter> permissionFilterList = collected.get(adminUserDto.getSysType());
        List<String> excludePermissionCode = new ArrayList<>();
        if (!CollectionUtils.isEmpty(permissionFilterList) && StringUtils.hasText(adminUserDto.getSn())) {
            MerchantInfoDO merchantInfoDO = merchantService.queryMerchant(adminUserDto.getSn());
            List<DataFilterConfig.PermissionFilter> collect = permissionFilterList.stream()
                    .filter(permissionFilter -> permissionFilter.getMerType().equals(merchantInfoDO.getMerType())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(collect)) {
                log.info("当前用户角色权限需要过滤");
                DataFilterConfig.PermissionFilter permissionFilter = collect.get(0);
                excludePermissionCode = permissionFilter.getPermissionCodes();
            }
        }
        if (!adminRoleFlag) {
            stopWatch.start("queryPermissionCodeByRoleCode");
            permissionMappingList = roleService.queryPermissionCodeByRoleCode(adminUserDto.getRoleCodes());
            List<String> finalPermissionMappingList = permissionMappingList.stream().map(RolePermissionMappingDO::getPermissionCode).collect(Collectors.toList());
            List<String> finalExcludePermissionCode = excludePermissionCode;
            finalPermissionList = permissionList.stream().filter(permissionDO -> finalPermissionMappingList.contains(permissionDO.getCode()))
                    .filter(permissionDO -> !finalExcludePermissionCode.contains(permissionDO.getCode())).collect(Collectors.toList());
            stopWatch.stop();
        }
        else {
            List<String> finalExcludePermissionCode = excludePermissionCode;
            finalPermissionList = permissionList.stream().filter(permissionDO -> !finalExcludePermissionCode.contains(permissionDO.getCode())).collect(Collectors.toList());
        }
        stopWatch.start("userPermissionDto");
        userPermissionDto.setAdminRoleFlag(adminRoleFlag);
        userPermissionDto.setPermissionList(finalPermissionList);
        userPermissionDto.setRolePermissionList(permissionMappingList);
        stopWatch.stop();
        if (log.isDebugEnabled()) {
            log.debug("userPermissionDto  total:{}, msg:{}", stopWatch.getTotalTimeMillis(), stopWatch.prettyPrint());
        }
        return CommonResult.success(userPermissionDto);
    }

    /**
     *
     * @param permissionList
     * @param adminUserCheckPermissionReq
     * @return
     */
    PermissionDO permissionDO(@NotNull List<PermissionDO> permissionList, AdminUserCheckPermissionReq adminUserCheckPermissionReq) {
        // 入参tag 不为null
        // if (StringUtils.hasText(adminUserCheckPermissionReq.getPermissionName())) {
        // PermissionDO permissionDO = permissionTag(permissionList,
        // adminUserCheckPermissionReq);
        // if (permissionDO != null) {
        // return permissionDO;
        // }
        // }
        // 入参tag 为null
        Map<String, List<PermissionDO>> permissionMap = permissionList.stream()
                .filter(permission -> permission.getUrl() != null && !permission.getUrl().contains(StringPool.LEFT_BRACE) && !permission.getUrl().contains(StringPool.NEWLINE))
                .collect(Collectors.groupingBy(permission -> permission.getUrl()));
        String method = adminUserCheckPermissionReq.getMethod().toUpperCase(Locale.ROOT).trim();
        String requestUrl = adminUserCheckPermissionReq.getUrl().trim();
        String url = method + " " + requestUrl.substring(1);
        // url 唯一 直接返回
        List<PermissionDO> permissionDOList = permissionMap.get(url);
        if (CollectionUtils.isNotEmpty(permissionDOList)) {
            return permissionDOList.get(0);
        }
        // url 不唯一 说明 url 有占位符 或者一个权限中存在多个url
        // 优先占位符 为了效率 先匹配请求方式 再匹配占位符
        List<PermissionDO> placeholders = permissionList.stream().filter(permissionDO -> permissionDO.getUrl() != null && permissionDO.getUrl().contains(method)
                && permissionDO.getUrl().contains(StringPool.LEFT_BRACE) && !permissionDO.getUrl().contains(StringPool.NEWLINE)).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(placeholders)) {
            for (PermissionDO permissionDO : placeholders) {
                boolean placeholder = placeholder(permissionDO.getUrl(), url);
                if (placeholder) {
                    return permissionDO;
                }
            }
        }
        // 其次分割符 为了效率 先匹配请求方式 再匹配分割符
        List<PermissionDO> segmentations = permissionList.stream()
                .filter(permissionDO -> permissionDO.getUrl() != null && permissionDO.getUrl().contains(method) && permissionDO.getUrl().contains(StringPool.NEWLINE))
                .collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(segmentations)) {
            for (PermissionDO permissionDO : segmentations) {
                boolean placeholder = segmentations(permissionDO.getUrl(), url);
                if (placeholder) {
                    return permissionDO;
                }
            }
        }
        return null;
    }

    /**
     *
     * @param permissionList
     * @param adminUserCheckPermissionReq
     * @return
     */
    PermissionDO permissionName(@NotNull List<PermissionDO> permissionList, AdminUserCheckPermissionReq adminUserCheckPermissionReq) {
        Map<String, List<PermissionDO>> permissionMap = permissionList.stream().collect(Collectors.groupingBy(permission -> permission.getName()));
        // String url = adminUserCheckPermissionReq.getMethod() + " " +
        // adminUserCheckPermissionReq.getUrl();
        // url +tag 唯一
        List<PermissionDO> permissionDOList = permissionMap.get(adminUserCheckPermissionReq.getPermissionName());
        if (CollectionUtils.isNotEmpty(permissionDOList) && permissionDOList.size() == 1) {
            return permissionDOList.get(0);
        }
        return null;
    }

    /**
     *
     * @param permissionList
     * @param userCheckPermissionReq
     * @return
     */
    PermissionDO permissionTag(@NotNull List<PermissionDO> permissionList, AdminUserCheckPermissionReq userCheckPermissionReq) {
        Map<String, List<PermissionDO>> permissionMap = permissionList.stream()
                .collect(Collectors.groupingBy(permission -> permissionUrlTag(permission.getUrl(), permission.getName())));
        String url = userCheckPermissionReq.getMethod() + " " + userCheckPermissionReq.getUrl().substring(1);
        // url +tag 唯一
        List<PermissionDO> permissionDOList = permissionMap.get(permissionUrlTag(url, userCheckPermissionReq.getPermissionName()));
        if (CollectionUtils.isNotEmpty(permissionDOList) && permissionDOList.size() == 1) {
            return permissionDOList.get(0);
        }
        Map<String, List<PermissionDO>> permissionNameMap = permissionList.stream().collect(Collectors.groupingBy(permissionDO -> permissionDO.getName()));

        List<PermissionDO> permissionNameList = permissionNameMap.get(userCheckPermissionReq.getPermissionName());
        if (CollectionUtils.isEmpty(permissionNameList)) {
            log.debug("permissionTag not find:{}", userCheckPermissionReq.getPermissionName());
            return null;
        }

        for (PermissionDO permissionDO : permissionNameList) {
            if (StringUtils.hasText(permissionDO.getUrl())) {
                continue;
            }
            String permissionUrl = permissionDO.getUrl();
            // 多个记录处理
            if (permissionUrl.contains(StringPool.LEFT_BRACE)) {
                boolean placeholder = placeholder(permissionUrl, url);
                if (placeholder) {
                    return permissionDO;
                }
            }
            else if (permissionUrl.contains(StringPool.NEWLINE)) {
                boolean segmentations = segmentations(permissionUrl, url);
                if (segmentations) {
                    return permissionDO;
                }
            }
            else {
                if (url.equals(permissionDO.getUrl())) {
                    return permissionDO;
                }
            }
        }
        return null;
    }

    /**
     * 分隔符处理
     * 
     * @param permissionUrl
     * @param url
     * @return
     */
    boolean segmentations(String permissionUrl, String url) {
        String[] split = permissionUrl.split(StringPool.NEWLINE);
        String placeholderUrl = null;
        for (int i = 0; i < split.length; i++) {
            try {
                String permissionSplitUrl = split[i];
                // 包含{}
                if (permissionSplitUrl.contains(StringPool.LEFT_BRACE)) {
                    placeholderUrl = url.substring(0, url.lastIndexOf(StringPool.SLASH) + 1) + permissionSplitUrl.substring(permissionSplitUrl.lastIndexOf(StringPool.LEFT_BRACE));
                }
                else {
                    placeholderUrl = url;
                }
                if (placeholderUrl.equals(permissionSplitUrl)) {
                    return true;
                }
            }
            catch (Exception e) {
                log.error("permissionDO error:{}", e.getMessage(), e);
                return false;
            }
        }
        return false;
    }

    /**
     * 占位符处理
     * 
     * @param permissionUrl
     * @param url
     * @return
     */
    boolean placeholder(String permissionUrl, String url) {
        try {
            String segmentationsUrl = url;
            // 包含{}
            segmentationsUrl = url.substring(0, url.lastIndexOf(StringPool.SLASH) + 1) + permissionUrl.substring(permissionUrl.lastIndexOf(StringPool.LEFT_BRACE));
            if (permissionUrl.equals(segmentationsUrl)) {
                return true;
            }
        }
        catch (Exception e) {
            log.error("permissionDO error:{}", e.getMessage(), e);
            return false;
        }
        return false;
    }

    String permissionUrlTag(String url, String tag) {
        if (url == null) {
            url = "";
        }
        return url + "-" + tag;
        // return url;
    }

    /**
     * user authority cache key
     * 
     * @param userId
     * @return
     */
    private String authorityKey(Long userId) {
        StringBuilder sb = new StringBuilder(AdminRedisConstant.USER_DATA_AUTHORITY);
        // sb.append(tenantId);
        // sb.append(StringPool.COLON);
        sb.append(userId);
        return sb.toString();
    }

    /**
     * user authority cache key
     * 
     * @param userId
     * @return
     */
    private String authorityKey(Long userId, String permissionName) {
        StringBuilder sb = new StringBuilder(AdminRedisConstant.USER_DATA_AUTHORITY);
        // sb.append(tenantId);
        // sb.append(StringPool.COLON);
        sb.append(userId);
        sb.append(StringPool.COLON);
        sb.append(permissionName);
        return sb.toString();
    }

    public static void main(String[] args) {
        String joson = "GET v1/common/config/platFormConfig\n" + "POST v1/common/config/platFormConfig";
        System.out.println();
    }

}
